import * as vscode from "vscode";
import { Command } from "../../../utils/commandManager";
import { nulToken } from "../../../utils/cancellation";
import { ITypeScriptServiceClient } from "../../../typescriptService";
import * as Proto from '../../../protocol';
import * as typeConverters from '../../../utils/typeConverters';

const 词典正则 = /(\s+)?\/\/##{(.+)?}/;

export class 格式化词典语句命令_ implements Command {
    public static readonly ID = '_ctsscript.格式化词典语句命令_';
    public readonly ID = 格式化词典语句命令_.ID;
    public 同步替换 = false;
    constructor(private client: ITypeScriptServiceClient) {
        this.同步替换 = vscode.workspace.getConfiguration('ctsscript').get("格式化词典同步替换标识符") as boolean;
    }
    public async execute() {
        const 当前编辑器 = vscode.window.activeTextEditor;
        if(!当前编辑器){
            return;
        }
        const 当前文档 = 当前编辑器.document;
        const 当前选择位置 = 当前编辑器.selection.anchor;
        const 当前行 = 当前文档.lineAt(当前选择位置.line);
        const 当前行文本 = 当前行.text;
        const 选择的词典体 = 当前行文本.match(词典正则) || [];
        if (选择的词典体.length >= 3) {
            let 词典内容主体 = 选择的词典体[2];
            if (词典内容主体) {
                const 整理后的内容主体 = this.编译词典(词典内容主体, this.同步替换);
                const 词典头 = this.同步替换 ? "//@@" : "//##";
                const 格式化后词典语句 = `${选择的词典体[1]! || ""}${词典头}{ ${整理后的内容主体} }`;
                const 替换范围 = new vscode.Range(new vscode.Position(当前选择位置.line, 0), new vscode.Position(当前选择位置.line, 当前行文本.length));
                if (this.同步替换) {
                    const 参数 = { file: 当前文档.fileName, line: 当前选择位置.line, offset: 当前选择位置.character, newNames: this.编译词典(词典内容主体) };
                    let 请求 = await this.client.execute("renameDictInfo", 参数, nulToken);
                    if (请求 && 请求.type === "response" && 请求.body && 请求.body.data) {
                        const 文件编辑数组 = 请求.body.data;
                        const 排除重复文件编辑组: Proto.FileCodeEdits[] = [];
                        for (let 当前编辑组 of 文件编辑数组) {
                            let 路径1 = this.client.normalizedPath(this.client.toResource(当前编辑组.fileName));
                            let 路径2 = this.client.normalizedPath(this.client.toResource(当前文档.fileName));
                            if (路径1 === 路径2) {
                                const 排除自身后文本改变组: Proto.CodeEdit[] = [];
                                for (let 改变范围 of 当前编辑组.textChanges) {
                                    if (改变范围.start.line !== 当前选择位置.line + 1) {
                                        排除自身后文本改变组.push(改变范围);
                                    }
                                }
                                排除重复文件编辑组.push({ fileName: 当前编辑组.fileName, textChanges: 排除自身后文本改变组 });
                            }
                            else {
                                排除重复文件编辑组.push(当前编辑组);
                            }
                        }
                        const 平台编辑 = typeConverters.WorkspaceEdit.fromFileCodeEdits(this.client, 排除重复文件编辑组);
                        平台编辑.replace(this.client.toResource(当前文档.fileName), 替换范围, 格式化后词典语句);
                        vscode.workspace.applyEdit(平台编辑);
                    }
                }
                else {
                    当前编辑器.edit(e => {
                        e.replace(替换范围, 格式化后词典语句);
                    });
                }
            }
        }
    }

    public 编译词典(词典体文本: string, 是否翻转 = false) {
        const 词组内容组 = 词典体文本.split(",");
        const 结果: string[] = [];
        for (let i = 0; i < 词组内容组.length; i++) {
            const 词典组 = 词组内容组[i];
            const 键值 = 词典组.split(":");
            if (键值.length === 2) {
                let 键 = 键值[0].trim();
                let 值 = 键值[1].trim();
                是否翻转 ? 结果.push(`${值}:${键}`) : 结果.push(`${键}:${值}`);
            }
        }
        return 结果.join(", ");
    }
}
